﻿using System;

namespace TurtleEngine.Helper.BackgroundWorker
{
	 /// <summary>
	 ///
	 /// </summary>
	 public static class BackgroundWorkerHelper
	 {
		  /// <summary>
		  ///
		  /// </summary>
		  public delegate void Func();

		  /// <summary>
		  /// Does the work.
		  /// </summary>
		  /// <typeparam name="Tin">The type of the in.</typeparam>
		  /// <typeparam name="Tout">The type of the out.</typeparam>
		  /// <param name="inputArgument">The input argument.</param>
		  /// <param name="doWork">The do work.</param>
		  /// <param name="workerCompleted">The worker completed.</param>
		  public static void DoWork<Tin, Tout>(
			  Tin inputArgument,
			  Func<DoWorkArgument<Tin>, Tout> doWork,
			  Action<WorkerResult<Tout>> workerCompleted)
		  {
				var bw = new System.ComponentModel.BackgroundWorker();
				bw.WorkerReportsProgress = false;
				bw.WorkerSupportsCancellation = false;
				bw.DoWork += (sender, args) =>
								{
									 if (doWork != null)
									 {
										  args.Result = doWork(new DoWorkArgument<Tin>((Tin)args.Argument));
									 }
								};
				bw.RunWorkerCompleted += (sender, args) =>
											{
												 if (workerCompleted != null)
												 {
													  workerCompleted(new WorkerResult<Tout>((Tout)args.Result, args.Error));
												 }
											};
				bw.RunWorkerAsync(inputArgument);
		  }

		  /// <summary>
		  /// Does the work.
		  /// </summary>
		  /// <typeparam name="Tout">The type of the out.</typeparam>
		  /// <param name="doWork">The do work.</param>
		  /// <param name="workerCompleted">The worker completed.</param>
		  public static void DoWork<Tout>(
			  Func<Tout> doWork,
			  Action<WorkerResult<Tout>> workerCompleted)
		  {
				var bw = new System.ComponentModel.BackgroundWorker();
				bw.WorkerReportsProgress = false;
				bw.WorkerSupportsCancellation = false;
				bw.DoWork += (sender, args) =>
								{
									 if (doWork != null)
									 {
										  args.Result = doWork();
									 }
								};
				bw.RunWorkerCompleted += (sender, args) =>
											{
												 if (workerCompleted != null)
												 {
													  workerCompleted(new WorkerResult<Tout>((Tout)args.Result, args.Error));
												 }
											};
				bw.RunWorkerAsync();
		  }

		  /// <summary>
		  /// Does the work.
		  /// </summary>
		  /// <param name="doWork">The do work.</param>
		  /// <param name="workerCompleted">The worker completed.</param>
		  public static void DoWork(
			  Func doWork,
			  Action<Exception> workerCompleted)
		  {
				var bw = new System.ComponentModel.BackgroundWorker();
				bw.WorkerReportsProgress = false;
				bw.WorkerSupportsCancellation = false;
				bw.DoWork += (sender, args) =>
								{
									 if (doWork != null)
									 {
										  doWork();
									 }
								};
				bw.RunWorkerCompleted += (sender, args) =>
											{
												 if (workerCompleted != null)
												 {
													  workerCompleted(args.Error);
												 }
											};
				bw.RunWorkerAsync();
		  }
	 }
}